package com.sanyuan.cloud.module.system.service.appauth.impl;

import cn.hutool.core.lang.UUID;
import com.sanyuan.cloud.framework.common.enums.CommonStatusEnum;
import com.sanyuan.cloud.framework.common.enums.NongmoUserTypeEnum;
import com.sanyuan.cloud.framework.common.enums.UserTypeEnum;
import com.sanyuan.cloud.framework.common.util.servlet.ServletUtils;
import com.sanyuan.cloud.module.system.api.logger.dto.LoginLogCreateReqDTO;
import com.sanyuan.cloud.module.system.controller.admin.auth.vo.AuthLoginRespVO;
import com.sanyuan.cloud.module.system.controller.app.appauth.req.AppAuthReqVO;
import com.sanyuan.cloud.module.system.dal.dataobject.user.AdminUserDO;
import com.sanyuan.cloud.module.system.enums.logger.LoginLogTypeEnum;
import com.sanyuan.cloud.module.system.enums.logger.LoginResultEnum;
import com.sanyuan.cloud.module.system.service.appauth.AppAuthService;
import com.sanyuan.cloud.module.system.service.auth.AdminAuthService;
import com.sanyuan.cloud.module.system.service.logger.LoginLogService;
import com.sanyuan.cloud.module.system.service.user.AdminUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Objects;

import static com.sanyuan.cloud.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.sanyuan.cloud.module.system.enums.ErrorCodeConstants.*;
import static com.sanyuan.cloud.module.system.enums.nongmo.AuthEnums.AUTY_TYPE_ADMIN;
import static com.sanyuan.cloud.module.system.enums.nongmo.AuthEnums.AUTY_TYPE_MEMEBER;

/**
 * @Description:
 * @Author: wuyuwei
 * @Date: 2025/3/28
 */
@Slf4j
@Service
public class AppAuthServiceImpl implements AppAuthService {


    @Resource
    private AdminAuthService adminAuthService;
    @Resource
    private AdminUserService userService;
    @Resource
    private LoginLogService loginLogService;

    @Override
    public AuthLoginRespVO login(AppAuthReqVO reqVO) {
        AdminUserDO userDO = authenticate(reqVO.getUsername(), reqVO.getPassword());
        if (reqVO.getType().equals(AUTY_TYPE_MEMEBER.getCode()) && NongmoUserTypeEnum.ADMIN.getValue().equals(userDO.getIsAdmin())){
            log.error("登录类型错误 reqVO:{}, userDO:{}",reqVO,userDO);
            throw exception(AUTH_LOGIN_TYPE_ERROR);
        }
        if (reqVO.getType().equals(AUTY_TYPE_ADMIN.getCode()) && !NongmoUserTypeEnum.ADMIN.getValue().equals(userDO.getIsAdmin())){
            log.error("登录类型错误 reqVO:{}, userDO:{}",reqVO,userDO);
            throw exception(AUTH_LOGIN_TYPE_ERROR);
        }
        return adminAuthService.createTokenAfterLoginSuccessByWeixinMini(userDO,LoginLogTypeEnum.LOGIN_USERNAME);
    }

    public AdminUserDO authenticate(String username, String password) {
        final LoginLogTypeEnum logTypeEnum = LoginLogTypeEnum.LOGIN_USERNAME;
        // 校验账号是否存在
        AdminUserDO user = userService.getUserByUsername(username);
        if (user == null) {
            createLoginLog(null, username, logTypeEnum, LoginResultEnum.BAD_CREDENTIALS);
            throw exception(AUTH_LOGIN_BAD_CREDENTIALS);
        }
        if (!userService.isPasswordMatch(password, user.getPassword())) {
            createLoginLog(user.getId(), username, logTypeEnum, LoginResultEnum.BAD_CREDENTIALS);
            throw exception(AUTH_LOGIN_BAD_CREDENTIALS);
        }
        // 校验是否禁用
        if (CommonStatusEnum.isDisable(user.getStatus())) {
            createLoginLog(user.getId(), username, logTypeEnum, LoginResultEnum.USER_DISABLED);
            throw exception(AUTH_LOGIN_USER_DISABLED);
        }
        return user;
    }

    private void createLoginLog(Long userId, String username,
                                LoginLogTypeEnum logTypeEnum, LoginResultEnum loginResult) {
        // 插入登录日志
        LoginLogCreateReqDTO reqDTO = new LoginLogCreateReqDTO();
        reqDTO.setLogType(logTypeEnum.getType());
        reqDTO.setTraceId(UUID.fastUUID().toString());
        reqDTO.setUserId(userId);
        reqDTO.setUserType(getUserType().getValue());
        reqDTO.setUsername(username);
        reqDTO.setUserAgent(ServletUtils.getUserAgent());
        reqDTO.setUserIp(ServletUtils.getClientIP());
        reqDTO.setResult(loginResult.getResult());
        loginLogService.createLoginLog(reqDTO);
        // 更新最后登录时间
        if (userId != null && Objects.equals(LoginResultEnum.SUCCESS.getResult(), loginResult.getResult())) {
            userService.updateUserLogin(userId, ServletUtils.getClientIP());
        }
    }

    private UserTypeEnum getUserType() {
        return UserTypeEnum.MEMBER;
    }
}
